home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Controls / Visual Basic Controls.iso / vbcontrol / srtsltn / data1.cab / Target / Samples / MFCSmpl / mfcsmplDlg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-05  |  12.3 KB  |  458 lines

  1. // Copyright ⌐ 1997 Mario M. Westphal
  2. // All Rights reserved
  3. // This source code is only intended as a supplement to the
  4. // Sort Solution user documentation and related
  5. // electronic documentation provided with the library.
  6. // See these sources for detailed information regarding the
  7. // Sort Solution product.
  8.  
  9. // ** See OnBtnExec() for integration details **
  10. //
  11.  
  12. #include "stdafx.h"
  13. #include "mfcsmpl.h"
  14. #include "mfcsmplDlg.h"
  15.  
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. // This application is used to edit the profile
  23. const TCHAR APP_NAME[] = _T("Notepad ");
  24.  
  25.  
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CAboutDlg dialog used for App About
  28. class CAboutDlg : public CDialog
  29. {
  30. public:
  31.     CAboutDlg();
  32.  
  33. // Dialog Data
  34.     //{{AFX_DATA(CAboutDlg)
  35.     enum { IDD = IDD_ABOUTBOX };
  36.     //}}AFX_DATA
  37.  
  38.     // ClassWizard generated virtual function overrides
  39.     //{{AFX_VIRTUAL(CAboutDlg)
  40.     protected:
  41.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  42.     //}}AFX_VIRTUAL
  43.  
  44. // Implementation
  45. protected:
  46.     //{{AFX_MSG(CAboutDlg)
  47.     //}}AFX_MSG
  48.     DECLARE_MESSAGE_MAP()
  49. };
  50.  
  51. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  52. {
  53.     //{{AFX_DATA_INIT(CAboutDlg)
  54.     //}}AFX_DATA_INIT
  55. }
  56.  
  57. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  58. {
  59.     CDialog::DoDataExchange(pDX);
  60.     //{{AFX_DATA_MAP(CAboutDlg)
  61.     //}}AFX_DATA_MAP
  62. }
  63.  
  64. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  65.     //{{AFX_MSG_MAP(CAboutDlg)
  66.         // No message handlers
  67.     //}}AFX_MSG_MAP
  68. END_MESSAGE_MAP()
  69.  
  70.  
  71.  
  72. /////////////////////////////////////////////////////////////////////////////
  73. // Callback for the Sort Solution DLL
  74. // This callback updates the progress controls to give the user some feedback
  75. // about the current state of the sort
  76. BOOL CALLBACK NotifyCallback(UINT Code, DWORD Status, DWORD Extra)
  77. {
  78.     CMfcsmplDlg* pdlg = (CMfcsmplDlg*)Extra;
  79.  
  80.     switch (Code)
  81.     {
  82.     case SORTSOL_NOTIFY_SORTPERCENTAGE:
  83.         VERIFY(pdlg->m_Progress_Sort.PostMessage(PBM_SETPOS, (int)Status, 0L));
  84.         break;
  85.  
  86.     case SORTSOL_NOTIFY_MERGEPERCENTAGE:
  87.         VERIFY(pdlg->m_Progress_Merge.PostMessage(PBM_SETPOS, (int)Status, 0L));
  88.         break;
  89.     
  90.     case SORTSOL_NOTIFY_BEGINSORT:
  91.         switch (Status) {
  92.         case SORTSOL_STATUS_ONEPHASESORT:
  93.             break;
  94.         case SORTSOL_STATUS_MERGESORT:
  95.             break;
  96.         }
  97.         break;
  98.     
  99.     case SORTSOL_NOTIFY_FINISHSORT:
  100.         break;
  101.     
  102.     case SORTSOL_NOTIFY_BEGINMERGE:
  103.         break;
  104.     
  105.     case SORTSOL_NOTIFY_FINISHMERGE:
  106.         break;
  107.  
  108.     case SORTSOL_NOTIFY_FINISHED:
  109.         break;
  110.     }
  111.  
  112.     // A simple way to keep the application responding
  113.     MSG msg;
  114.     while (::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE)) { 
  115.         AfxGetApp()->PumpMessage();
  116.     } 
  117.  
  118.     // Continue with sort while m_Running remains true
  119.     // m_Running will be set to FALSE if the user aborts the sort
  120.     return pdlg->IsRunning();
  121. }
  122.  
  123.  
  124.  
  125. /////////////////////////////////////////////////////////////////////////////
  126. // CMfcsmplDlg dialog
  127. CMfcsmplDlg::CMfcsmplDlg(CWnd* pParent /*=NULL*/)
  128.     : CDialog(CMfcsmplDlg::IDD, pParent)
  129. {
  130.     //{{AFX_DATA_INIT(CMfcsmplDlg)
  131.     m_Static_BytesSorted = _T("0");
  132.     m_Static_OutputFile = _T("");
  133.     m_Static_LogFile = _T("");
  134.     m_Static_RecsSorted = _T("0");
  135.     m_Static_Time = _T("?");
  136.     m_Static_RecsFiltered = _T("0");
  137.     //}}AFX_DATA_INIT
  138.     // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  139.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  140.  
  141.     
  142.     // Some additional initializations
  143.     m_Running = FALSE;
  144. }
  145.  
  146.  
  147. /////////////////////////////////////////////////////////////////////////////
  148. // 
  149. void CMfcsmplDlg::DoDataExchange(CDataExchange* pDX)
  150. {
  151.     CDialog::DoDataExchange(pDX);
  152.     //{{AFX_DATA_MAP(CMfcsmplDlg)
  153.     DDX_Control(pDX, IDC_BTN_EDIT, m_Btn_Edit);
  154.     DDX_Control(pDX, IDC_EDIT_FILENAME, m_Edit_FileName);
  155.     DDX_Control(pDX, IDCANCEL, m_Btn_Cancel);
  156.     DDX_Control(pDX, IDC_PROGRESS_SORT, m_Progress_Sort);
  157.     DDX_Control(pDX, IDC_PROGRESS_MERGE, m_Progress_Merge);
  158.     DDX_Control(pDX, IDC_BTN_EXEC, m_Btn_Exec);
  159.     DDX_Control(pDX, IDC_BTN_BROWSE, m_Btn_Browse);
  160.     DDX_Text(pDX, IDC_STATIC_BYTESSORTED, m_Static_BytesSorted);
  161.     DDX_Text(pDX, IDC_STATIC_OUTPUTFILE, m_Static_OutputFile);
  162.     DDX_Text(pDX, IDC_STATIC_LOGFILE, m_Static_LogFile);
  163.     DDX_Text(pDX, IDC_STATIC_RECSSORTED, m_Static_RecsSorted);
  164.     DDX_Text(pDX, IDC_STATIC_TIME, m_Static_Time);
  165.     DDX_Text(pDX, IDC_STATIC_RECSFILTERED, m_Static_RecsFiltered);
  166.     //}}AFX_DATA_MAP
  167. }
  168.  
  169.  
  170. BEGIN_MESSAGE_MAP(CMfcsmplDlg, CDialog)
  171.     //{{AFX_MSG_MAP(CMfcsmplDlg)
  172.     ON_WM_SYSCOMMAND()
  173.     ON_WM_PAINT()
  174.     ON_WM_QUERYDRAGICON()
  175.     ON_BN_CLICKED(IDC_BTN_BROWSE, OnBtnBrowse)
  176.     ON_BN_CLICKED(IDC_BTN_EXEC, OnBtnExec)
  177.     ON_EN_CHANGE(IDC_EDIT_FILENAME, OnChangeEditFilename)
  178.     ON_BN_CLICKED(IDC_BTN_EDIT, OnBtnEdit)
  179.     //}}AFX_MSG_MAP
  180. END_MESSAGE_MAP()
  181.  
  182.  
  183. /////////////////////////////////////////////////////////////////////////////
  184. // 
  185. BOOL CMfcsmplDlg::OnInitDialog()
  186. {
  187.     CDialog::OnInitDialog();
  188.  
  189.     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  190.     ASSERT(IDM_ABOUTBOX < 0xF000);
  191.  
  192.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  193.     if (pSysMenu != NULL)
  194.     {
  195.         CString strAboutMenu;
  196.         strAboutMenu.LoadString(IDS_ABOUTBOX);
  197.         if (!strAboutMenu.IsEmpty())
  198.         {
  199.             pSysMenu->AppendMenu(MF_SEPARATOR);
  200.             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  201.         }
  202.     }
  203.  
  204.     SetIcon(m_hIcon, TRUE);            // Set big icon
  205.     SetIcon(m_hIcon, FALSE);        // Set small icon
  206.  
  207.     m_Btn_Exec.EnableWindow(FALSE);
  208.     m_Progress_Sort.SetRange(0,100);
  209.     m_Progress_Merge.SetRange(0,100);
  210.     m_Btn_Edit.EnableWindow(FALSE);
  211.  
  212.     return TRUE;  // return TRUE  unless you set the focus to a control
  213. }
  214.  
  215.  
  216. /////////////////////////////////////////////////////////////////////////////
  217. // 
  218. void CMfcsmplDlg::OnSysCommand(UINT nID, LPARAM lParam)
  219. {
  220.     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  221.     {
  222.         CAboutDlg dlgAbout;
  223.         dlgAbout.DoModal();
  224.     }
  225.     else
  226.     {
  227.         CDialog::OnSysCommand(nID, lParam);
  228.     }
  229. }
  230.  
  231.  
  232. /////////////////////////////////////////////////////////////////////////////
  233. // If you add a minimize button to your dialog, you will need the code below
  234. //  to draw the icon.  For MFC applications using the document/view model,
  235. //  this is automatically done for you by the framework.
  236. void CMfcsmplDlg::OnPaint() 
  237. {
  238.     if (IsIconic())
  239.     {
  240.         CPaintDC dc(this); // device context for painting
  241.  
  242.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  243.  
  244.         // Center icon in client rectangle
  245.         int cxIcon = GetSystemMetrics(SM_CXICON);
  246.         int cyIcon = GetSystemMetrics(SM_CYICON);
  247.         CRect rect;
  248.         GetClientRect(&rect);
  249.         int x = (rect.Width() - cxIcon + 1) / 2;
  250.         int y = (rect.Height() - cyIcon + 1) / 2;
  251.  
  252.         // Draw the icon
  253.         dc.DrawIcon(x, y, m_hIcon);
  254.     }
  255.     else
  256.     {
  257.         CDialog::OnPaint();
  258.     }
  259. }
  260.  
  261.  
  262. /////////////////////////////////////////////////////////////////////////////
  263. // The system calls this to obtain the cursor to display while the user drags
  264. //  the minimized window.
  265. HCURSOR CMfcsmplDlg::OnQueryDragIcon()
  266. {
  267.     return (HCURSOR) m_hIcon;
  268. }
  269.  
  270.  
  271. /////////////////////////////////////////////////////////////////////////////
  272. // Only allow to exit the application when the sort is not running
  273. void CMfcsmplDlg::OnCancel() 
  274. {
  275.     if (m_Running) {
  276.         CString strtab;
  277.         VERIFY(strtab.LoadString(IDS_CLOSEINFO));
  278.         AfxMessageBox(strtab,MB_ICONEXCLAMATION | MB_OK);
  279.         return;
  280.     }
  281.     CDialog::OnCancel();
  282. }
  283.  
  284.  
  285. /////////////////////////////////////////////////////////////////////////////
  286. // Display a file open common control
  287. void CMfcsmplDlg::OnBtnBrowse() 
  288. {
  289.     CString strtab;
  290.     VERIFY(strtab.LoadString(IDS_FILEMASK));
  291.     CFileDialog dlg(TRUE, _T("*.ssp"), NULL, OFN_OVERWRITEPROMPT,strtab);
  292.  
  293.     if (dlg.DoModal() == IDOK) {
  294.         m_Edit_FileName.SetWindowText(dlg.GetPathName());
  295.     }
  296. }
  297.  
  298.  
  299. /////////////////////////////////////////////////////////////////////////////
  300. // Display an error message for error code "Code"
  301. void CMfcsmplDlg::ShowErrorMessage(int Code)
  302. {
  303.     CString msg;
  304.     LPTSTR lpc = msg.GetBuffer(255);
  305.     unsigned long len = 255;
  306.     SSIGetErrorMessage(Code,lpc,&len);
  307.     msg.ReleaseBuffer(-1);
  308.     AfxMessageBox(msg,MB_ICONSTOP | MB_OK);
  309. }
  310.  
  311.  
  312. /////////////////////////////////////////////////////////////////////////////
  313. // This method handles both "Start" and "Stop".
  314. void CMfcsmplDlg::OnBtnExec() 
  315. {
  316.     // If the sort is running...
  317.     if (m_Running) {
  318.         // This will trigger the callback NotifyCallback() to return FALSE
  319.         // the next time it it called from the sort DLL
  320.         m_Running = FALSE;
  321.         // Don't let the user press that button again until the sort is
  322.         // stopped
  323.         m_Btn_Exec.EnableWindow(FALSE);
  324.     }
  325.     else {
  326.         m_Running = TRUE;
  327.         // Disable the front end while the sort is running
  328.         m_Btn_Cancel.EnableWindow(FALSE);
  329.         m_Btn_Browse.EnableWindow(FALSE);
  330.         m_Btn_Edit.EnableWindow(FALSE);
  331.         // Change the button title
  332.         CString strtab;
  333.         VERIFY(strtab.LoadString(IDS_BTNSTOP));
  334.         m_Btn_Exec.SetWindowText(strtab);
  335.  
  336.         // Update the front end
  337.         m_Progress_Sort.SetPos(0);
  338.         m_Progress_Merge.SetPos(0);
  339.  
  340.         
  341.         // Update the dialog to display the new values
  342.         m_Static_LogFile = _T("");
  343.         m_Static_BytesSorted = _T("0");
  344.         m_Static_RecsSorted = _T("0");
  345.         m_Static_RecsFiltered = _T("0");
  346.         m_Static_Time = _T("?");
  347.         UpdateData(FALSE);
  348.         
  349.         // Setup the profile status. Since we don't want to
  350.         // override any of the commands from the profile,
  351.         // we zero it out
  352.         // Don't forget to initialize the size member
  353.         SORTSOL_CMDFILESTATUS cmdstat;
  354.         memset(&cmdstat,0,sizeof(cmdstat));
  355.         cmdstat.uSize = sizeof(cmdstat);
  356.  
  357.         // Setup the stats structure. Zero it out and 
  358.         // intitialize the uSize member
  359.         SORTSOL_STATS stats;
  360.         memset(&stats,0x0,sizeof(stats));
  361.         stats.uSize = sizeof(stats);
  362.  
  363.         // Now create a new sort instance. This step will read the command
  364.         // file, check it for validity and return some information in "cmdstat"
  365.         int res;
  366.         SSIH ssihandle;
  367.  
  368.         // Get the profile name from the dialog
  369.         CString profile;
  370.         m_Edit_FileName.GetWindowText(profile);
  371.         res = SSICreateFromFile(&ssihandle, profile, &cmdstat);
  372.         
  373.         if (res == SOSOERR_SUCCESS) {
  374.             // Display some of the information contained in cmdstat
  375.             m_Static_OutputFile = cmdstat.OutputFileName;
  376.             m_Static_LogFile = cmdstat.LogFileName;
  377.             UpdateData(FALSE);
  378.  
  379.             // Register the callback function
  380.             SSIRegisterCallback(ssihandle,NotifyCallback,(DWORD)this);
  381.             
  382.             // Let the sort do it's work...
  383.             res = SSISort(ssihandle);
  384.             
  385.             // If everything went fine, get the stats. We will use this
  386.             // information a bit later to display some statistical information
  387.             if (res == SOSOERR_SUCCESS) {
  388.                 SSIGetStats(ssihandle, &stats);
  389.             }
  390.             
  391.             // Free the sort instance. This will reclaim all memory and
  392.             // other resources used by the sort
  393.             SSIFree(ssihandle);
  394.         }
  395.  
  396.         // If we have an error condition, display an appropriate message
  397.         if (res != SOSOERR_SUCCESS) {
  398.             ShowErrorMessage(res);
  399.         }
  400.         else {
  401.             // Display the stats
  402.             TCHAR ac[100];
  403.             sprintf(ac,_T("%I64d"),stats.liBytesSorted);
  404.             m_Static_BytesSorted = ac;
  405.             
  406.             sprintf(ac,_T("%I64d"),stats.liRecordsProcessed);
  407.             m_Static_RecsSorted = ac;
  408.  
  409.             sprintf(ac,_T("%I64d"),stats.liRecordsFiltered);
  410.             m_Static_RecsFiltered = ac;
  411.  
  412.             m_Static_Time.Format(_T("%u s"),(stats.dwSortTime+stats.dwMergeTime)/1000);
  413.  
  414.             UpdateData(FALSE);
  415.  
  416.             // And we're finished!
  417.             CString strtab1,strtitle;
  418.             VERIFY(strtab.LoadString(IDS_SORTCOMPLETED));
  419.             VERIFY(strtitle.LoadString(IDS_SOSO_TITLE));
  420.  
  421.             MessageBox(strtab,strtitle,MB_ICONEXCLAMATION | MB_OK);
  422.         }
  423.  
  424.         // Reactivate the front end...
  425.         m_Running = FALSE;
  426.         m_Btn_Cancel.EnableWindow(TRUE);
  427.         m_Btn_Exec.EnableWindow(TRUE);
  428.         VERIFY(strtab.LoadString(IDS_BTNEXEC));
  429.         m_Btn_Exec.SetWindowText(strtab);
  430.         m_Btn_Browse.EnableWindow(TRUE);
  431.         m_Btn_Edit.EnableWindow(TRUE);
  432.     }
  433. }
  434.  
  435.  
  436. /////////////////////////////////////////////////////////////////////////////
  437. // Active/Deactivate the buttons depending on the content of the edit field
  438. void CMfcsmplDlg::OnChangeEditFilename() 
  439. {
  440.     CString s;
  441.     m_Edit_FileName.GetWindowText(s);
  442.     m_Btn_Exec.EnableWindow(!s.IsEmpty());
  443.     m_Btn_Edit.EnableWindow(!s.IsEmpty());
  444. }
  445.  
  446.  
  447. /////////////////////////////////////////////////////////////////////////////
  448. // Launch Notepad to allow the user to edit the profile
  449. // - cheap but working
  450. void CMfcsmplDlg::OnBtnEdit() 
  451. {
  452.     CString filename;
  453.     m_Edit_FileName.GetWindowText(filename);
  454.  
  455.     
  456.     WinExec(APP_NAME + filename,SW_SHOWNORMAL);
  457. }
  458.